package javaAdvanced;

/**
 * @author cuiH
 * Date: 13-10-23
 */
public class TraditionalThreadCommunication {
    /*
    * 线程同步问题
    * 分析：main函数是第一个线程，当你创建时刻便已经拥有，因此先走main thread
    * 假想资源问题：只有一个休息的房间，老板和小弟轮流休息，老板休息5天，小弟可以休息2天，依次循环50次。（资源共享）
    * */
    public static void main(String[] args) {
        final RestRoom restRoom = new RestRoom();          //进行调用
        new Thread(
                new Runnable() {
                    @Override
                    public void run() {
                        //子线程进行50个10循环
                        for (int i = 1; i <= 100; i++) {
                            /*
                            * 字节码进行加锁TraditionalThreadCommunication.class 最简单的方式
                            * 可以使用，但是不适合比较大的程序
                            * 采用面向对象的方式，将相关联的方法处理为一个对象
                            * filter拦截就是一种同步机制
                            * */
//                            synchronized (TraditionalThreadCommunication.class) {
//                                for (int j = 1; j <= 10; j++) {
//                                    System.out.println("sub thread sequence " + i + " loop of " + j);
//                                }
//                            }
                            try {
                                restRoom.coder(i);
                            } catch (InterruptedException e) {
                                e.printStackTrace();
                            }
                        }
                    }
                }
        ).start();

        //main线程进行50 个10 循环
        for (int i = 1; i <= 100; i++) {
            try {
                restRoom.boss(i);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
//            synchronized (TraditionalThreadCommunication.class) {
//                for (int j = 1; j <= 10; j++) {
//                    System.out.println("main thread sequence " + j + " loop of " + i);
//                }
//            }
        }
    }

}

/*
* 要用到共同数据，包括同步锁的若干方法。
* 应该归在同一个类上，这种设计提高了系统的高类聚和程序的健壮性
* 此处写法采用信号量机制，进行互锁 ，控制
* 在资源代码上面进行互斥调用
* */
class RestRoom {
    private boolean bShouldBoss = true;

    public synchronized void coder(int i) throws InterruptedException {
        if (!bShouldBoss) {
            this.wait();                 //等待
        }
        for (int j = 1; j <= 2; j++) {
            System.out.println("小弟休息第 " + j + " 天，第" + i + " 次休息");
        }
        bShouldBoss = false;
        this.notify();//唤醒进程
    }

    public synchronized void boss(int i) throws InterruptedException {
        if (bShouldBoss) {
            this.wait();                           //等待
        }
        for (int j = 1; j <= 5; j++) {
            System.out.println("老板休息第 " + j + " 天，第" + i + " 次休息");
        }
        bShouldBoss = true;
        this.notify();                             //释放资源
    }
}


